#include "Render.h"

CRender::CRender(void)
{
	m_iWidth = 0;
	m_iHeight = 0;
	m_iMapWidth = 0;
	m_iMapHeight = 0;
}

CRender::~CRender(void)
{
}

int CRender::Render(const CModel model)
{
	m_Model = model;
	// get state from the model
	int result = m_Model.GetPlayState();

	if (result == TITLE)
		TitleScreen();
	else if (result == MENU)
		MainMenu();
	else if (result == NEWGAME)
		PickPlayer();
	else if (result == SETPLAYER)
		SetPlayers();
	else if (result == HELP)
		HelpScreen();
	else if (result == STATUS)
		StatusScreen();
	else if (result == TEST)
		TestScreen();
	else if (result == SETPOSITION)
		GameScreen();
	else if (result == GAME)
		GameScreen();
	else if (result == WINNING)
		WinScreen();

	Present();
	return OK;
}

void CRender::Present()
{
	int counter = 0;
	for (int h = 0; h < m_iHeight; h++)
	{
		for (int g = 0; g < m_iWidth; g++)
		{
			cout << m_vFinalCharMatrix[counter++];
		}
		cout << endl;
	}
}

int CRender::Initialization(int width, int height)
{
	m_iWidth = width;
	m_iHeight = height;

	m_vFinalCharMatrix.resize(width * height);

	for (int i = 0; i < m_vFinalCharMatrix.size(); i++)
		m_vFinalCharMatrix[i] = '0';

	// read map file
	ifstream read;
	read.open("map.txt");

	m_vMap.resize((width / 5) * (height / 5));
	for (int h = 0; h < m_vMap.size(); h++)
			read >> m_vMap[h];
	read.close();

	m_iMapWidth = width / 5;
	m_iMapHeight = height /5;

	return OK;
}

void CRender::ClearFinalMatrix()
{
	for (int i = 0; i < m_vFinalCharMatrix.size(); i++)
		m_vFinalCharMatrix[i] = NULL;
}

void CRender::Border()
{
	// set border
	for (int i = 0; i < m_iWidth; i++)
	{
		m_vFinalCharMatrix[i] = '*'; // top line
		m_vFinalCharMatrix[i + (m_iWidth * m_iHeight - m_iWidth)] = '*'; // bottom line
	}
	for (int h = 0; h < m_iHeight; h++)
	{
		m_vFinalCharMatrix[m_iWidth * h] = '*';
		m_vFinalCharMatrix[m_iWidth * h + m_iWidth - 1] = '*';
	}
}

void CRender::Text(const char *string, int row, int shift)
{
	int i = 0;
	while(string[i] != NULL)
		m_vFinalCharMatrix[m_iWidth * row + shift++] = string[i++];

//	for (int i = 0; i < sizeof(string); i++)
//		m_vFinalCharMatrix[m_iWidth * row + shift++] =  string[i];
}

void CRender::Text(const char c, int row, int shift)
{
	m_vFinalCharMatrix[m_iWidth * row + shift] = c;
}

void CRender::Text(const int i, int row, int shift)
{
	char convert[10];
	memset(convert, NULL, sizeof(convert));
	itoa(i, convert, 10);
	Text(convert, row, shift);
}

int CRender::WinScreen()
{
	ClearFinalMatrix();
	Border();

	int x = 12;
	int y = 15;

	int player = m_Model.GetNext();
	m_Model.GetPlayers(m_CPU, m_Human);

	vector<CCPU>::iterator CPU_iter;
	vector<CHuman>::iterator Human_iter;

	// find who is playing
	Text("Player:", y, x);
	x += 7;
	for (Human_iter = m_Human.begin(); Human_iter != m_Human.end(); Human_iter++)
	{
		if (Human_iter->GetOrder() == player)
		{
			Text(Human_iter->GetName(), y, x);
		}
	}

	for (CPU_iter = m_CPU.begin(); CPU_iter != m_CPU.end(); CPU_iter++)
	{
		if (CPU_iter->GetOrder() == player)
		{
			Text(CPU_iter->GetName(), y, x);
		}
	}

	Text("won the game!", y + 3, x);

	Text("Press Spacebar", 30, 40);

	return OK;
}

int CRender::TitleScreen()
{
	ClearFinalMatrix();
	Border();

	Text("Theft", 8, 10);
	Text("By Travis Smith", 13, 15);
	Text("   Victor Cortez", 14, 15);
	Text("Press Spacebar", 30, 40);
	Text("TIP: press ESC any time to exit the program", 36, 30);

	//m_vFinalCharMatrix[200] = char(176);
	//char a[100];
	//cin >> a;
/*
	char string[20];
	memset(string, NULL, sizeof(string));	
	strcat(string, "Theft");
	// row, shift
	int row = 8;
	int shift = 10;
	
	for (int i = 0; i < sizeof(string); i++)
		m_vFinalCharMatrix[m_iWidth * row + shift++] =  string[i];


	memset(string, NULL, sizeof(string));	
	strcat(string, "By Travis Smith");
	row = 13;
	shift = 15;

	for (int i = 0; i < sizeof(string); i++)
		m_vFinalCharMatrix[m_iWidth * row + shift++] =  string[i];

	memset(string, NULL, sizeof(string));	
	strcat(string, "Press Spacebar");
	row = 30;
	shift = 40;

	for (int i = 0; i < sizeof(string); i++)
		m_vFinalCharMatrix[m_iWidth * row + shift++] =  string[i];
*/

	return OK;
}

int CRender::MainMenu()
{
	ClearFinalMatrix();
	Border();

	int x = 33;
	int y = 12;
	int shift = 2;

	Text("1. New Game", y, x);
	y = shift + y;
	//Text("2. Load Game", y, x);
	//y = shift + y;
	Text("3. Help", y, x);
	y = shift + y;
	Text("4. Exit", y, x);
	y = 5 + y;
	x = x - 10;
	Text("Please pick number between 1 to 4", y, x);

	return OK;
}

int CRender::LoadScreen()
{
	ClearFinalMatrix();
	Border();

	int x = 22;
	int y = 12;
	int shift = 2;

	Text("Please select a game to load", y++, x);
	Text("from the list below", y, x);
	y = shift + y;
	Text("1.", y, ++x);
	y = shift + y;
	Text("2.", y, x);
	y = shift + y;
	Text("3.", y, x);
	y = shift + y;
	Text("4.", y, x);
	y = shift + y;
	Text("5.", y, x);
	y = shift + y;
	Text("Please choose a number", y, --x);

	return OK;
}

int CRender::PickPlayer()
{
	ClearFinalMatrix();
	Border();

	int x = 14;
	int y = 15;
	int shift = 2;

	Text("Please pick the number of players 2 to 6", y, x);

	return OK;
}

int CRender::SetPlayers()
{
	ClearFinalMatrix();
	Border();

	int x = 18;
	int y = 12;
	int shift = 2;

	// too lazy to deal string, so I made if else statements here
	int next = m_Model.GetNext();
	if (next == 1)
		Text("Please choose a number 1 or 2 for Player 1", y, x);
	else if (next == 2)
		Text("Please choose a number 1 or 2 for Player 2", y, x);
	else if (next == 3)
		Text("Please choose a number 1 or 2 for Player 3", y, x);
	else if (next == 4)
		Text("Please choose a number 1 or 2 for Player 4", y, x);
	else if (next == 5)
		Text("Please choose a number 1 or 2 for Player 5", y, x);
	else if (next == 6)
		Text("Please choose a number 1 or 2 for Player 6", y, x);

	y = shift + y;
	Text("1. Human", y, x);
	y = shift + y;
	Text("2. CPU", y, x);

	return OK;
}

int CRender::SaveScreen()
{
	ClearFinalMatrix();
	Border();

	int x = 18;
	int y = 12;
	int shift = 2;

	Text("Please choose a number to save below: ", y, x);

	y = shift + y;
	Text("1.", y, ++x);
	y = shift + y;
	Text("2.", y, x);
	y = shift + y;
	Text("3.", y, x);
	y = shift + y;
	Text("4.", y, x);
	y = shift + y;
	Text("5.", y, x);
	y = shift + y;

	return OK;
}

int CRender::HelpScreen()
{
	ClearFinalMatrix();
	Border();

	Text("Under Construction", 13, 25);
	Text("Press Spacebar", 30, 27);

	return OK;
}

int CRender::StatusScreen()
{
	ClearFinalMatrix();
	Border();

	m_Model.GetPlayers(m_CPU, m_Human);

	Text("Status", 3, 7);

	int x = 10;
	int y = 5;
	int shift = 2;
	vector<CCPU>::iterator CPU_iter;
	vector<CHuman>::iterator Human_iter;

	for (int i = 1; i <= m_Model.GetNumberPlayers(); i++)
	{
		// CPU
		for (CPU_iter = m_CPU.begin(); CPU_iter != m_CPU.end(); CPU_iter++)
		{
			if (CPU_iter->GetOrder() == i)
			{
				if (i == 1)
					Text("Player 1:", y++, x);
				else if (i == 2)
					Text("Player 2:", y++, x);
				else if (i == 3)
					Text("Player 3:", y++, x);
				else if (i == 4)
					Text("Player 4:", y++, x);
				else if (i == 5)
					Text("Player 5:", y++, x);
				else if (i == 6)
					Text("Player 6:", y++, x);
				
				// name
				Text("Name:", y, x + 2);
				Text(CPU_iter->GetName(), y++, x + 8);

				// money
				Text("Money:", y, x + 2);
				Text(CPU_iter->GetBalance(), y++, x + 9);

				// icon
				Text("Icon:", y, x + 2);
				Text((char)CPU_iter->GetIcon(), y++, x + 8);

				// direction
				Text("Direction:", y - 3, x + 20);
				if (CPU_iter->GetDirection() == NORTH)
					Text("UP", y - 3, x + 31);
				else if (CPU_iter->GetDirection() == EAST)
					Text("Left", y - 3, x + 31);
				else if (CPU_iter->GetDirection() == WEST)
					Text("Right", y - 3, x + 31);
				else if (CPU_iter->GetDirection() == SOUTH)
					Text("Down", y - 3, x + 31);
				else if (CPU_iter->GetDirection() == NOWHERE)
					Text("NULL", y - 3, x + 31);
				//Text(CPU_iter->GetDirection(), y - 3, x + 31);
			}
		}

		// human
		for (Human_iter = m_Human.begin(); Human_iter != m_Human.end(); Human_iter++)
		{
			if (Human_iter->GetOrder() == i)
			{
				if (i == 1)
					Text("Player 1:", y++, x);
				else if (i == 2)
					Text("Player 2:", y++, x);
				else if (i == 3)
					Text("Player 3:", y++, x);
				else if (i == 4)
					Text("Player 4:", y++, x);
				else if (i == 5)
					Text("Player 5:", y++, x);
				else if (i == 6)
					Text("Player 6:", y++, x);

				// name
				Text("Name:", y, x + 2);
				Text(Human_iter->GetName(), y++, x + 8);

				// money
				Text("Money:", y, x + 2);
				Text(Human_iter->GetBalance(), y++, x + 9);

				// icon
				Text("Icon:", y, x + 2);
				Text((char)Human_iter->GetIcon(), y++, x + 8);

				// direction
				Text("Direction:", y - 3, x + 20);
				if (Human_iter->GetDirection() == NORTH)
					Text("UP", y - 3, x + 31);
				else if (Human_iter->GetDirection() == EAST)
					Text("Left", y - 3, x + 31);
				else if (Human_iter->GetDirection() == WEST)
					Text("Right", y - 3, x + 31);
				else if (Human_iter->GetDirection() == SOUTH)
					Text("Down", y - 3, x + 31);
				else if (Human_iter->GetDirection() == NOWHERE)
					Text("NULL", y - 3, x + 31);
			}
		}
		y++;
	}

	Text("Press Spacebar", 35, 50);

	//Text(m_CPU.begin()->GetName(), 12, 12);
	//m_vFinalCharMatrix[21] = char(m_CPU.begin()->GetIcon());
	
	return OK;
}

int CRender::GameScreen()
{
	ClearFinalMatrix();
	Board();
	Keyword();
	PlayStatus();

	//if (m_Model.GetPlayState() != SETPOSITION)
		Position();
	// clear matrix
	// board
	// player position
	// key words
	// score
	// play status

	return OK;
}

int CRender::PlayStatus()
{
	int y = 26;
	int x = 61;
	bool IsHuman = false;

	int player = m_Model.GetNext();
	m_Model.GetPlayers(m_CPU, m_Human);

	vector<CCPU>::iterator CPU_iter;
	vector<CHuman>::iterator Human_iter;


	// find who is playing
	Text("Player", y++, x++);
	for (Human_iter = m_Human.begin(); Human_iter != m_Human.end(); Human_iter++)
	{
		if (Human_iter->GetOrder() == player)
		{
			IsHuman = true;
			break;
		}
	}

	if (!IsHuman)
	{
		for (CPU_iter = m_CPU.begin(); CPU_iter != m_CPU.end(); CPU_iter++)
		{
			if (CPU_iter->GetOrder() == player)
			{
				IsHuman = false;
				break;
			}
		}
	}


	if (IsHuman)
	{
		Text("Name:", y, x);
		Text(Human_iter->GetName(), y++, x + 6);
		Text("Icon:", y, x);
		Text((char)Human_iter->GetIcon(), y++, x + 6);
		Text("Money:", y, x);
		Text(Human_iter->GetBalance(), y++, x + 7);
		Text("Direction:", y, x);
		if (Human_iter->GetDirection() == NORTH)
			Text("UP", y++, x + 11);
		else if (Human_iter->GetDirection() == EAST)
			Text("Right", y++, x + 11);
		else if (Human_iter->GetDirection() == WEST)
			Text("Left", y++, x + 11);
		else if (Human_iter->GetDirection() == SOUTH)
			Text("Down", y++, x + 11);
		else if (Human_iter->GetDirection() == NOWHERE)
			Text("NULL", y++, x + 11);
		Text("Move:", y, x);
		Text(Human_iter->GetMove(), y, x + 5);
	}
	else
	{
		Text("Name:", y, x);
		Text(CPU_iter->GetName(), y++, x + 6);
		Text("Icon:", y, x);
		Text((char)CPU_iter->GetIcon(), y++, x + 6);
		Text("Money:", y, x);
		Text(CPU_iter->GetBalance(), y++, x + 7);
		Text("Direction:", y, x);
		if (CPU_iter->GetDirection() == NORTH)
			Text("UP", y++, x + 11);
		else if (CPU_iter->GetDirection() == EAST)
			Text("Right", y++, x + 11);
		else if (CPU_iter->GetDirection() == WEST)
			Text("Left", y++, x + 11);
		else if (CPU_iter->GetDirection() == SOUTH)
			Text("Down", y++, x + 11);
		else if (CPU_iter->GetDirection() == NOWHERE)
			Text("NULL", y++, x + 11);
	}

	//---------------------------------------

	if (m_Model.GetPlayState() == SETPOSITION)
	{
		if (IsHuman)
		{
			y = y + 3;
			Text("Pick 1 to 4 to", y++, x);
			Text("put on start", y++, x);
			Text("1,2,3 or 4", y++, x);
			Text("square", y++, x);
		}
		else 
		{
			y = y + 3;
			Text("Press Spacebar", y++, x);
		}
	}
	else if (m_Model.GetPlayState() == GAME)
	{
		if (IsHuman)
		{
			if (Human_iter->GetState() == MOVE)
			{
				y = y + 3;
				Text("Press Spacebar", y++, x);
				Text("to roll a dice", y++, x);
			}
			else if (Human_iter->GetState() == DIRECTION)
			{
				bool right, left, up, down;
				y = y + 3;
				Human_iter->GetPossibleDirection(right, left, up, down);
				Text("Pick one:", y++, x);
				if (up)
					Text("UP arrow", y++, x);
				if (down)
					Text("DOWN arrow", y++, x);
				if (right)
					Text("RIGHT arrow", y++, x);
				if (left)
					Text("LEFT arrow", y++, x);
				Text("to set direction", y++, x);
			}
			else if (Human_iter->GetState() == END)
			{
				// how did the player rob?
				y = y + 2;
				Text("Rob:", y, x);
				Text(Human_iter->GetRob(), y++, x + 5);
				Text("End turn", y, x);
				y = y + 2;
				Text("Press Spacebar", y++, x);
			}
		}
		else
		{
			if (CPU_iter->GetState() == _SPACEBAR)
			{
				y = y + 2;
				Text("Press Spacebar", y++, x);
				//Text("to start",y++, x);
			}
			else if (CPU_iter->GetState() == _END)
			{
				y = y + 2;
				Text("Rob:", y, x);
				Text(CPU_iter->GetRob(), y++, x + 5);
				Text("End turn", y, x);
				y = y + 2;
				Text("Press Spacebar", y++, x);
			}
		}
	}

	return OK;
}

void CRender::Position()
{
	m_Model.GetPlayers(m_CPU, m_Human);

	vector<CCPU>::iterator CPU_iter;
	vector<CHuman>::iterator Human_iter;

	for (CPU_iter = m_CPU.begin(); CPU_iter != m_CPU.end(); CPU_iter++)
	{
		PositionBoard(CPU_iter->GetOrder(), CPU_iter->GetPosition().x, 
			CPU_iter->GetPosition().y, CPU_iter->GetIcon());
		
	}
	for (Human_iter = m_Human.begin(); Human_iter != m_Human.end(); Human_iter++)
	{
		PositionBoard(Human_iter->GetOrder(), Human_iter->GetPosition().x, 
			Human_iter->GetPosition().y, Human_iter->GetIcon());
		
	}
}

void CRender::PositionBoard(int order, int x, int y, int icon)
{
	int set = m_iWidth * y * 5 + x * 5;

	set = m_iWidth * 2 + set + 2; // center of a square

	if (order == 1)
		m_vFinalCharMatrix[set - m_iWidth - 1] = (char)icon;
	else if (order == 2)
		m_vFinalCharMatrix[set - 1] = (char)icon;
	else if (order == 3)
		m_vFinalCharMatrix[set + m_iWidth - 1] = (char)icon;
	else if (order == 4)
		m_vFinalCharMatrix[set - m_iWidth + 1] = (char)icon;
	else if (order == 5)
		m_vFinalCharMatrix[set + 1] = (char)icon;
	else if (order == 6)
		m_vFinalCharMatrix[set + m_iWidth + 1] = (char)icon;
}
int CRender::Keyword()
{
	int y = 26;
	int x = 1;

	Text("Key words", y, x++);
	y = y + 2;
	Text("* Store  $5", y++, x);
	Text("^ Bank   $10", y++, x);
	Text("& Museum $20", y++, x);
	Text("% Tip", y++, x);
	Text("$ Theft", y++, x);
	Text("H Safe House", y++, x);

	y++;
	Text("Press V to", y++, x);
	Text("view status", y++, x);
	y++;
	//Text("Press S to", y++, x);
	//Text("save the game", y, x);

	return OK;
}

int CRender::Board()
{
	//ClearFinalMatrix();

	int count = 0;
	int x = 2;
	int y = 2;
	
	for (int i = 0; i < m_iHeight / 5; i++)
	{
		for (int h = 0; h < m_iWidth / 5; h++)
		{
			if (m_vMap[count] == '8')
				Square(x, y, NULL);
			else if (m_vMap[count] == '1')
				Square(x, y, '1');
			else if (m_vMap[count] == '7')
				Square(x, y, 'H');
			else if (m_vMap[count] == '6')
				Square(x, y, '$');
			else if (m_vMap[count] == '5')
				Square(x, y, '%');
			else if (m_vMap[count] == '4')
				Square(x, y, '&');
			else if (m_vMap[count] == '3')
				Square(x, y, '*');
			else if (m_vMap[count] == '2')
				Square(x, y, '^');
			else if (m_vMap[count] == '9')
				Square(x, y, '2');
			else if (m_vMap[count] == 'a')
				Square(x, y, '3');
			else if (m_vMap[count] == 'b')
				Square(x, y, '4');

			x = x + 5;
			count++;
		}
		x = 2;
		y = y + 5;
	}
	
	return OK;
}

int CRender::Square(int x, int y, char c)
{
	m_vFinalCharMatrix[m_iWidth * y + x - 2] = char(179);
	m_vFinalCharMatrix[m_iWidth * y + x + 2] = char(179);
	m_vFinalCharMatrix[m_iWidth * (y - 1) + x - 2] = char(179);
	m_vFinalCharMatrix[m_iWidth * (y - 1) + x + 2] = char(179);
	m_vFinalCharMatrix[m_iWidth * (y + 1) + x - 2] = char(179);
	m_vFinalCharMatrix[m_iWidth * (y + 1) + x + 2] = char(179);

	m_vFinalCharMatrix[m_iWidth * (y + 2) + x] = char(196);
	m_vFinalCharMatrix[m_iWidth * (y - 2) + x] = char(196);
	m_vFinalCharMatrix[m_iWidth * (y + 2) + x - 1] = char(196);
	m_vFinalCharMatrix[m_iWidth * (y - 2) + x - 1] = char(196);
	m_vFinalCharMatrix[m_iWidth * (y + 2) + x + 1] = char(196);
	m_vFinalCharMatrix[m_iWidth * (y - 2) + x + 1] = char(196);

	m_vFinalCharMatrix[m_iWidth * (y + 2) + x + 2] = char(217);
	m_vFinalCharMatrix[m_iWidth * (y + 2) + x - 2] = char(192);
	m_vFinalCharMatrix[m_iWidth * (y - 2) + x + 2] = char(191);
	m_vFinalCharMatrix[m_iWidth * (y - 2) + x - 2] = char(218);

	m_vFinalCharMatrix[m_iWidth * y + x] = c;

	return OK;
}

int CRender::TestScreen()
{
	//ClearFinalMatrix();

	int count = 0;
/*	
	for (int i = 0; i < m_iHeight / 5; i++)
		for (int h = 0; h < m_iWidth / 5; h++)
			m_vFinalCharMatrix[m_iWidth * i + h] = m_vMap[count++];
*/

/*
	int x = 2;
	int y = 2;

	//Square(x, y, NULL);

	
	for (int i = 0; i < m_iHeight / 5; i++)
	{
		for (int h = 0; h < m_iWidth / 5; h++)
		{
			if (m_vMap[count] == '8')
				Square(x, y, NULL);
			else if (m_vMap[count] == '1')
				Square(x, y, 'S');
			else if (m_vMap[count] == '7')
				Square(x, y, 'H');
			x = x + 5;
			count++;
		}
		x = 2;
		y = y + 5;
	}
*/	
	GameScreen();
	//Square(10, 20, NULL);

	return OK;
}